package qualomelhor.server;

import qualomelhor.database.*;
import qualomelhor.util.Util;

import com.google.appengine.api.datastore.Blob;
import com.google.appengine.api.images.Composite;
import com.google.appengine.api.images.Image;
import com.google.appengine.api.images.ImagesService;
import com.google.appengine.api.images.ImagesServiceFactory;
import com.google.appengine.api.images.Transform;
import com.googlecode.objectify.*; 
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map.Entry;

import org.apache.commons.io.IOUtils;

import com.googlecode.objectify.util.DAOBase;
import qualomelhor.database.BuscaProduto;
import qualomelhor.database.Categoria;
import qualomelhor.database.LinkBlobImage;
import qualomelhor.database.Comparacao.TipoComparacao;
import qualomelhor.database.Email;
import qualomelhor.database.ParametrosSistema;
import qualomelhor.database.ParametrosSistema.OrigemLogin;
import qualomelhor.database.ParametrosSistema.SiteHost;
import qualomelhor.database.Produto;
import qualomelhor.database.Usuario;
import qualomelhor.gwt.modules.client.ClientUtils;

public class DAO extends DAOBase {

	static {
		ObjectifyService.register(Usuario.class);
		System.out.println("Registrou Usuario...");
		ObjectifyService.register(ParametrosSistema.class);
		System.out.println("Registrou ParametrosSistema...");
		ObjectifyService.register(Produto.class);
		System.out.println("Registrou Produto...");
		ObjectifyService.register(BuscaProduto.class);
		System.out.println("Registrou BuscaProduto...");
		ObjectifyService.register(Categoria.class);
		System.out.println("Registrou Categoria...");
		ObjectifyService.register(Email.class);
		System.out.println("Registrou Email...");
		ObjectifyService.register(Comparacao.class);
		System.out.println("Registrou Comparacao...");
		ObjectifyService.register(LinkComparacao.class);
		System.out.println("Registrou LinkComparacao...");
		ObjectifyService.register(PosicaoMaosDB.class);
		System.out.println("Registrou PosicaoMaosDB...");
		ObjectifyService.register(ExpressaoDB.class);
		System.out.println("Registrou ExpressaoDB...");
		ObjectifyService.register(SequenciaExpressaoDB.class);
		System.out.println("Registrou SequenciaExpressaoDB...");
		ObjectifyService.register(TermoIdioma.class);
		System.out.println("Registrou TermoIdioma...");
		ObjectifyService.register(LinkCategoria_Produto.class);
		System.out.println("Registrou LinkCategoria_Produto...");
		ObjectifyService.register(BuscaComparacao.class);
		System.out.println("Registrou BuscaComparacao...");
		ObjectifyService.register(LinkBlobImage.class);
		System.out.println("Registrou LinkBlobImage...");
	}

	public ArrayList<PosicaoMaosDB> getListaPosicaoMaos() {
		Query<PosicaoMaosDB> listPosicaoMaos = ofy().query(PosicaoMaosDB.class);

	    ArrayList<PosicaoMaosDB> listPosicaoMaosTmp = new ArrayList<PosicaoMaosDB>(0);
	    for (PosicaoMaosDB par: listPosicaoMaos) {
	        listPosicaoMaosTmp.add(par);
	    }

	    return listPosicaoMaosTmp;
	}

	public ArrayList<ExpressaoDB> getListaExpressaoDB() {
		Query<ExpressaoDB> listExpressao = ofy().query(ExpressaoDB.class).order("nome");

	    ArrayList<ExpressaoDB> listExpressaoTmp = new ArrayList<ExpressaoDB>(0);
	    for (ExpressaoDB par: listExpressao) {
	    	listExpressaoTmp.add(par);
	    }

	    return listExpressaoTmp;
	}

	public ArrayList<SequenciaExpressaoDB> getListaSequenciaExpressaoDB() {
		Query<SequenciaExpressaoDB> listSeqExpressao = ofy().query(SequenciaExpressaoDB.class);

	    ArrayList<SequenciaExpressaoDB> listSeqExpressaoTmp = new ArrayList<SequenciaExpressaoDB>(0);
	    for (SequenciaExpressaoDB par: listSeqExpressao) {
	    	listSeqExpressaoTmp.add(par);
	    }

	    return listSeqExpressaoTmp;
	}

	public ArrayList<ParametrosSistema> getListaSistema() {
		Query<ParametrosSistema> listSistema = ofy().query(ParametrosSistema.class);
		//Query<Horotimo> listHorotimo = ofy().query(Horotimo.class).offset(offset).limit(limit);
	    ArrayList<ParametrosSistema> listSistemaTmp = new ArrayList<ParametrosSistema>(0);
	    for (ParametrosSistema par: listSistema) {
	        listSistemaTmp.add(par);
	    }

	    return listSistemaTmp;
	}

	public ParametrosSistema getSistema() {
		ParametrosSistema result = null;
	    Iterable<ParametrosSistema> listParSist = ofy().query(ParametrosSistema.class);

	    if (listParSist.iterator().hasNext()) {
	    	result = (ParametrosSistema)listParSist.iterator().next();
	    }

	    return result;
	}

	public ArrayList<Produto> getListaProdutos(Long idCategoria) {
		Query<Produto> listProduto = ofy().query(Produto.class).filter("idCategoria", idCategoria);
	    ArrayList<Produto> listProdutoTmp = new ArrayList<Produto>(0);
	    for (Produto hor: listProduto) {
	        listProdutoTmp.add(hor);
	    }

	    return listProdutoTmp;
	}

	public ArrayList<Produto> getListaProdutoSimilar(Produto p, ArrayList<Produto> listTodosOsProdutos) {

		ArrayList<Produto> listProdutoTmp = new ArrayList<Produto>(0);
		for (int i = 0; i < listTodosOsProdutos.size(); i++) {
			Produto pSim = listTodosOsProdutos.get(i);
			if (
					p.getNomeProduto().equals(pSim.getNomeProduto())
					||
					p.getDescricao().equals(pSim.getDescricao())
					||
					p.getListEnderecoFoto().removeAll(pSim.getListEnderecoFoto())
					||
					p.getEnderecoFotoMini().equals(pSim.getEnderecoFotoMini())
					//||
					//p.getPath().equals(pSim.getPath())
					||
					p.getListBusca().removeAll(pSim.getListBusca())
				) {

				//Tem similaridade

				listProdutoTmp.add(pSim);
			}
		}

	    return listProdutoTmp;
	}

	@SuppressWarnings("unchecked")
	public ArrayList<Produto> getListaProdutos(boolean recarregar) {

		ArrayList<Produto> listProdutoTmp = null;
		if (!recarregar) {
			listProdutoTmp = (ArrayList<Produto>)MemCacheData.getData("LISTPRODUTO");
		}
		if (listProdutoTmp == null || listProdutoTmp.size() == 0) {
			listProdutoTmp = new ArrayList<Produto>(0);
			Query<Produto> listProduto = ofy().query(Produto.class);

			for (Produto hor: listProduto) {
				listProdutoTmp.add(hor);
			}
			MemCacheData.putData("LISTPRODUTO", listProdutoTmp);
		}

	    return listProdutoTmp;
	}

	@SuppressWarnings("unchecked")
	public ArrayList<Comparacao> getListaComparacao(boolean recarregar) {

		ArrayList<Comparacao> listComparacaoTmp = null;
		if (!recarregar) {
			listComparacaoTmp = (ArrayList<Comparacao>)MemCacheData.getData("LISTCOMPARACAO");
		}
		if (listComparacaoTmp == null || listComparacaoTmp.size() == 0) {
			listComparacaoTmp = new ArrayList<Comparacao>(0);
			Query<Comparacao> listComparacao = ofy().query(Comparacao.class);

			for (Comparacao comp: listComparacao) {
				listComparacaoTmp.add(comp);
			}
			MemCacheData.putData("LISTCOMPARACAO", listComparacaoTmp);
		}

	    return listComparacaoTmp;
	}

	public ArrayList<Comparacao> getListaComparacao(Long idProduto1, Long idProduto2) {

		ArrayList<Comparacao> listComparacaoTmp = new ArrayList<Comparacao>(0);
		ArrayList<BuscaComparacao> listBuscaTmp = new ArrayList<BuscaComparacao>(0);

		Query<BuscaComparacao> listBuscaComp = ofy().query(BuscaComparacao.class).filter("idProduto", idProduto1);
		for (BuscaComparacao comp: listBuscaComp) {
			listBuscaTmp.add(comp);
		}

		Query<BuscaComparacao> listBuscaComp2 = ofy().query(BuscaComparacao.class).filter("idProduto", idProduto2);
		for (BuscaComparacao comp: listBuscaComp2) {
			listBuscaTmp.add(comp);
		}

		for (BuscaComparacao bsc: listBuscaTmp) {
			listComparacaoTmp.add(getComparacao(bsc.getIdComparacao()));
		}

	    return listComparacaoTmp;
	}

	@SuppressWarnings("unchecked")
	public ArrayList<ParteAvatar> getListaParteAvatar(boolean recarregar) {

		ArrayList<ParteAvatar> listParteTmp = null;
		if (!recarregar) {
			listParteTmp = (ArrayList<ParteAvatar>)MemCacheData.getData("LISTPARTEAVATAR");
		}
		if (listParteTmp == null || listParteTmp.size() == 0) {
			listParteTmp = new ArrayList<ParteAvatar>(0);
			Query<ParteAvatar> listParteAvatar = ofy().query(ParteAvatar.class);

			for (ParteAvatar p: listParteAvatar) {
				listParteTmp.add(p);
			}
			MemCacheData.putData("LISTPARTEAVATAR", listParteTmp);
		}

	    return listParteTmp;
	}

	public ArrayList<BuscaProduto> getListaBuscaProduto() {
		@SuppressWarnings("unchecked")
		ArrayList<BuscaProduto> listBuscaTmp = (ArrayList<BuscaProduto>)MemCacheData.getData("LISTBUSCAPRODUTO");
		if (listBuscaTmp == null || listBuscaTmp.size() == 0) {
			listBuscaTmp = new ArrayList<BuscaProduto>(0);
			Query<BuscaProduto> listBusca = ofy().query(BuscaProduto.class);

			for (BuscaProduto hor: listBusca) {
				listBuscaTmp.add(hor);
			}
			MemCacheData.putData("LISTBUSCAPRODUTO", listBuscaTmp);
		}

	    return listBuscaTmp;
	}

	public ArrayList<LinkBlobImage> getListaLinkBlobImage(int offset, int limit) {
		ArrayList<LinkBlobImage> listBlobImageTmp = new ArrayList<LinkBlobImage>(0);
		Query<LinkBlobImage> listBlobImage = ofy().query(LinkBlobImage.class).offset(offset).limit(limit);

		for (LinkBlobImage b: listBlobImage) {
			listBlobImageTmp.add(b);
		}

	    return listBlobImageTmp;
	}

	public ArrayList<BuscaProduto> getListaBuscaProduto(Long idProd1, Long idProd2) {
		ArrayList<BuscaProduto> listBuscaTmp = new ArrayList<BuscaProduto>(0);
		Query<BuscaProduto> listBusca = ofy().query(BuscaProduto.class).filter("idProduto", idProd1);
		for (BuscaProduto bscP: listBusca) {
			listBuscaTmp.add(bscP);
		}

		Query<BuscaProduto> listBusca2 = ofy().query(BuscaProduto.class).filter("idProduto", idProd2);
		for (BuscaProduto bscP: listBusca2) {
			listBuscaTmp.add(bscP);
		}

	    return listBuscaTmp;
	}

	public ArrayList<BuscaComparacao> getListaBuscaComparacao(Long idProd1, Long idProd2) {
		ArrayList<BuscaComparacao> listBuscaTmp = new ArrayList<BuscaComparacao>(0); 

		Query<BuscaComparacao> listBusca = ofy().query(BuscaComparacao.class).filter("idProduto", idProd1);
		for (BuscaComparacao bsc: listBusca) {
			listBuscaTmp.add(bsc);
		}

		if (idProd2 != null) {
			Query<BuscaComparacao> listBusca2 = ofy().query(BuscaComparacao.class).filter("idProduto", idProd2);
			for (BuscaComparacao bsc: listBusca2) {
				listBuscaTmp.add(bsc);
			}
		}

	    return listBuscaTmp;
	}

	public ArrayList<BuscaComparacao> getListaBuscaComparacao(Long idComparacao) {
		ArrayList<BuscaComparacao> listBuscaTmp = new ArrayList<BuscaComparacao>(0); 

		Query<BuscaComparacao> listBusca = ofy().query(BuscaComparacao.class).filter("idComparacao", idComparacao);
		for (BuscaComparacao bsc: listBusca) {
			listBuscaTmp.add(bsc);
		}

	    return listBuscaTmp;
	}

	public ArrayList<BuscaComparacao> getListaBuscaComparacao() {
		ArrayList<BuscaComparacao> listBuscaTmp = new ArrayList<BuscaComparacao>(0); 
		Query<BuscaComparacao> listBusca = ofy().query(BuscaComparacao.class);
		for (BuscaComparacao bsc: listBusca) {
			listBuscaTmp.add(bsc);
		}

	    return listBuscaTmp;
	}

	public ArrayList<BuscaComparacao> getListaBuscaComparacao(int offset, int limit) {
		ArrayList<BuscaComparacao> listBuscaTmp = new ArrayList<BuscaComparacao>(0); 

		Query<BuscaComparacao> listBusca = ofy().query(BuscaComparacao.class).order("-id").offset(offset).limit(limit);
		for (BuscaComparacao bsc: listBusca) {
			listBuscaTmp.add(bsc);
		}

	    return listBuscaTmp;
	}

	public ArrayList<Comparacao> getListaComparacao(Long idProduto) {
		ArrayList<BuscaComparacao> listBuscaTmp = new ArrayList<BuscaComparacao>(0); 
		ArrayList<Comparacao> result = new ArrayList<Comparacao>(0);

		Query<BuscaComparacao> listBusca = ofy().query(BuscaComparacao.class).filter("idProduto", idProduto);
		for (BuscaComparacao bsc: listBusca) {
			listBuscaTmp.add(bsc);
		}

		for (BuscaComparacao bsc: listBuscaTmp) {
			result.add(getComparacao(bsc.getIdComparacao()));
		}

	    return result;
	}

	public ArrayList<Comparacao> getListaComparacao(Long idProduto, int limit) {
		ArrayList<BuscaComparacao> listBuscaTmp = new ArrayList<BuscaComparacao>(0); 
		ArrayList<Comparacao> result = new ArrayList<Comparacao>(0);

		Query<BuscaComparacao> listBusca = ofy().query(BuscaComparacao.class).filter("idProduto", idProduto).order("-id").limit(limit);
		for (BuscaComparacao bsc: listBusca) {
			listBuscaTmp.add(bsc);
		}

		for (BuscaComparacao bsc: listBuscaTmp) {
			result.add(getComparacao(bsc.getIdComparacao()));
		}

	    return result;
	}

	public ArrayList<LinkComparacao> getListaLinkComparacao() {
		@SuppressWarnings("unchecked")
		ArrayList<LinkComparacao> listLinkTmp = (ArrayList<LinkComparacao>)MemCacheData.getData("LISTLINKCOMPARACAO");
		if (listLinkTmp == null || listLinkTmp.size() == 0) {
			listLinkTmp = new ArrayList<LinkComparacao>(0);
			Query<LinkComparacao> listLink = ofy().query(LinkComparacao.class);

			for (LinkComparacao lc: listLink) {
				listLinkTmp.add(lc);
			}
			MemCacheData.putData("LISTLINKCOMPARACAO", listLinkTmp);
		}

	    return listLinkTmp;
	}

	@SuppressWarnings("unchecked")
	public ArrayList<LinkCategoria_Produto> getListaLinkCategoria_Produto(boolean recarregar) {

		ArrayList<LinkCategoria_Produto> listLinkTmp = null;
		if (!recarregar) {
			listLinkTmp = (ArrayList<LinkCategoria_Produto>)MemCacheData.getData("LISTLINKCATEGORIA_PRODUTO");
		}
		if (listLinkTmp == null || listLinkTmp.size() == 0) {
			listLinkTmp = new ArrayList<LinkCategoria_Produto>(0);
			Query<LinkCategoria_Produto> listLink = ofy().query(LinkCategoria_Produto.class);

			for (LinkCategoria_Produto lcp: listLink) {
				listLinkTmp.add(lcp);
			}
			MemCacheData.putData("LISTLINKCATEGORIA_PRODUTO", listLinkTmp);
		}

	    return listLinkTmp;
	}

	public ArrayList<LinkComparacao> getListaLinkComparacao(Long idComparacao) {
		ArrayList<LinkComparacao> listLinkTmp = new ArrayList<LinkComparacao>(0);
		Query<LinkComparacao> listLinkComp = ofy().query(LinkComparacao.class).filter("idComparacao", idComparacao);

		for (LinkComparacao l: listLinkComp) {
			listLinkTmp.add(l);
		}

	    return listLinkTmp;
	}

	public ArrayList<LinkCategoria_Produto> getListaLinkCategoria(Long idCategoria) {
		ArrayList<LinkCategoria_Produto> listLinkTmp = new ArrayList<LinkCategoria_Produto>(0);
		Query<LinkCategoria_Produto> listLinkComp = ofy().query(LinkCategoria_Produto.class).filter("idCategoria", idCategoria);

		for (LinkCategoria_Produto l: listLinkComp) {
			listLinkTmp.add(l);
		}

	    return listLinkTmp;
	}

	public ArrayList<LinkCategoria_Produto> getListaLinkProduto(Long idProduto) {
		ArrayList<LinkCategoria_Produto> listLinkTmp = new ArrayList<LinkCategoria_Produto>(0);
		Query<LinkCategoria_Produto> listLinkComp = ofy().query(LinkCategoria_Produto.class).filter("idProduto", idProduto);

		for (LinkCategoria_Produto l: listLinkComp) {
			listLinkTmp.add(l);
		}

	    return listLinkTmp;
	}

	public LinkCategoria_Produto getLinkProduto(Long idProduto, String locale) {
		LinkCategoria_Produto linkTmp = null;
		Query<LinkCategoria_Produto> listLinkComp = ofy().query(LinkCategoria_Produto.class).filter("idProduto", idProduto).filter("locale", locale);

		if (listLinkComp.iterator().hasNext()) {
			linkTmp = listLinkComp.iterator().next();
		}

	    return linkTmp;
	}

	public ArrayList<TermoIdioma> getListaTermoIdioma(int offset, int limit, boolean orderByLocaleFirst, boolean somenteSemTraducao) {
		System.out.println("DAO.getListaTermoIdioma()...");
		ArrayList<TermoIdioma> listTermoTmp = new ArrayList<TermoIdioma>(0);
		Query<TermoIdioma> listTermo = ofy().query(TermoIdioma.class);
		if (somenteSemTraducao) {
			listTermo = listTermo.filter("traducao", "");
		}
		if (orderByLocaleFirst) {
			listTermo = listTermo.order("locale").order("termo").offset(offset).limit(100);
		} else {
			listTermo = listTermo.order("termo").order("locale").offset(offset).limit(100);
		}
		System.out.println("DAO.getListaTermoIdioma()...while..");
		System.out.println("listTermo.size = " + listTermo.count());

		for (TermoIdioma t: listTermo) {
			System.out.println("DAO.getListaTermoIdioma()...dentro do for..");
			listTermoTmp.add(t);
		}

	    return listTermoTmp;
	}

	@SuppressWarnings("unchecked")
	public ArrayList<Categoria> getListaCategorias(boolean recarregar) {

		ArrayList<Categoria> listCategoriaTmp = null;
		if (!recarregar) {
			listCategoriaTmp = (ArrayList<Categoria>)MemCacheData.getData("LISTCATEGORIA");
		}
		if (listCategoriaTmp == null || listCategoriaTmp.size() == 0) {
			listCategoriaTmp = new ArrayList<Categoria>(0);
			Query<Categoria> listCategoria = ofy().query(Categoria.class).order("ordem");

			for (Categoria hor: listCategoria) {
				listCategoriaTmp.add(hor);
			}
			MemCacheData.putData("LISTCATEGORIA", listCategoriaTmp);
		}

	    return listCategoriaTmp;
	}

	@SuppressWarnings("unchecked")
	public ArrayList<Categoria> getListaCategoriasNivel0(boolean recarregar) {

		ArrayList<Categoria> listCategoriaTmp = null;
		if (!recarregar) {
			listCategoriaTmp = (ArrayList<Categoria>)MemCacheData.getData("LISTCATEGORIANIVEL0");
		}
		if (listCategoriaTmp == null || listCategoriaTmp.size() == 0) {
			listCategoriaTmp = new ArrayList<Categoria>(0);
			Query<Categoria> listCategoria = ofy().query(Categoria.class).filter("nivel", Byte.valueOf((byte)0)).order("ordem");

			for (Categoria hor: listCategoria) {
				listCategoriaTmp.add(hor);
			}
			MemCacheData.putData("LISTCATEGORIANIVEL0", listCategoriaTmp);
		}

	    return listCategoriaTmp;
	}

	@SuppressWarnings("unchecked")
	public ArrayList<Comparacao> getListaUltimasComparacoes(int limit, boolean recarregar) {

		ArrayList<Comparacao> listComparacaoTmp = null;
		if (!recarregar) {
			listComparacaoTmp = (ArrayList<Comparacao>)MemCacheData.getData("LISTULTIMASCOMPARACOES");
		}
		if (listComparacaoTmp == null || listComparacaoTmp.size() == 0) {
			listComparacaoTmp = new ArrayList<Comparacao>(0);
			Query<Comparacao> listComparacao = ofy().query(Comparacao.class).order("-dataInclusao").limit(limit);

			for (Comparacao comp: listComparacao) {
				listComparacaoTmp.add(comp);
			}
			MemCacheData.putData("LISTULTIMASCOMPARACOES", listComparacaoTmp);
		}

	    return listComparacaoTmp;
	}

	@SuppressWarnings("unchecked")
	public ArrayList<Comparacao> getListaUltimasComparacoes(SiteHost site, String locale, int limit, boolean recarregar) {

		ArrayList<Comparacao> listComparacaoTmp = null;
		if (!recarregar) {
			listComparacaoTmp = (ArrayList<Comparacao>)MemCacheData.getData("LISTULTIMASCOMPARACOES_" + site.getIdSite());
		}
		if (listComparacaoTmp == null || listComparacaoTmp.size() == 0) {
			listComparacaoTmp = new ArrayList<Comparacao>(0);
			Query<Comparacao> listComparacao = ofy().query(Comparacao.class).filter("site", site).order("-dataInclusao").limit(limit);

			for (Comparacao comp: listComparacao) {
				listComparacaoTmp.add(comp);
			}

			if (listComparacaoTmp.size() < limit) {
				Query<Comparacao> listComparacao2 = ofy().query(Comparacao.class).filter("locale", locale).order("-dataInclusao").limit(limit);
				for (Comparacao comp: listComparacao2) {
					if (!listComparacaoTmp.contains(comp)) {
						listComparacaoTmp.add(comp);
					}
				}
			}

			MemCacheData.putData("LISTULTIMASCOMPARACOES_" + site.getIdSite(), listComparacaoTmp);
		}

	    return listComparacaoTmp;
	}

	/*
	public Boolean mesclarProduto (Lond idProduto1, Lond idProduto2) {
		Produto p1 = getProduto(idProduto1);
		Produto p2 = getProduto(idProduto2);
		
		if ((p1.getDescricao() == null || p1.getDescricao().equals("")) && p2.getDescricao().equals(""))
		p1.set
	}
	*/

	public Produto getProduto(Long idProduto) {
		Produto result = null;
		try {
			result = ofy().get(Produto.class, idProduto);
		} catch (com.googlecode.objectify.NotFoundException e) {
			System.out.println("Produto id: " + idProduto + " nao encontrado!");
			e.printStackTrace();
		}

	    return result;
	}

	public ParteAvatar getParteAvatar(Long idParteAvatar) {
		ParteAvatar result = null;
		result = ofy().get(ParteAvatar.class, idParteAvatar);
	    return result;
	}

	public Categoria getCategoria(Long idCategoria) {
		Categoria result = null;
		result = ofy().get(Categoria.class, idCategoria);

	    return result;
	}

	public LinkComparacao getLinkComparacao(Long idLink) {
		LinkComparacao result = null;
		result = ofy().get(LinkComparacao.class, idLink);

	    return result;
	}

	public Comparacao getComparacao(Long idComparacao) {
		Comparacao result = null;
		try {
			result = ofy().get(Comparacao.class, idComparacao);
		} catch (com.googlecode.objectify.NotFoundException e) {
			System.out.println("erro ao carregar o id = " + idComparacao);
			e.printStackTrace();
		}
	    return result;
	}

	public LinkBlobImage getLinkBlobImage(Long idBlobImage) {
		LinkBlobImage result = null;
		try {
			result = ofy().get(LinkBlobImage.class, idBlobImage);
		} catch (Exception e) {
			System.out.println("linkBlobImage nao encontrado");
			//nao encontrado
		}
	    return result;
	}

	public Categoria getCategoriaByName(String nomeCategoria) {
		Categoria result = null;
		Query<Categoria> listCategoria = ofy().query(Categoria.class).filter("nomeCategoria", nomeCategoria);

		if (listCategoria.iterator().hasNext()) {
			result = listCategoria.iterator().next(); 
		}

	    return result;
	}

	public Comparacao getComparacaByImgVersus(String linkImgVersus) {
		Comparacao result = null;
		Query<Comparacao> listComparacao = ofy().query(Comparacao.class).filter("linkImgVersus", linkImgVersus).limit(1);

		if (listComparacao.iterator().hasNext()) {
			result = listComparacao.iterator().next(); 
		}

	    return result;
	}

	public TermoIdioma getTermoIdioma(Long id) {
		TermoIdioma result = null;
		result = ofy().get(TermoIdioma.class, id);
	    return result;
	}

	public TermoIdioma getTermoIdioma(String term, String locale) {
		TermoIdioma result = null;
		Query<TermoIdioma> listTermo = ofy().query(TermoIdioma.class).filter("termo", term).filter("locale", locale);
		if (listTermo.iterator().hasNext()) {
			result = listTermo.iterator().next();
		}
	    return result;
	}

	public PosicaoMaosDB getPosicaoMaoDB(String nome) {
		PosicaoMaosDB result = null;
		Query<PosicaoMaosDB> listPosMao = ofy().query(PosicaoMaosDB.class).filter("nome", nome);
		if (listPosMao.iterator().hasNext()) {
			result = listPosMao.iterator().next();
			System.out.println("posMao encontrada...");
		} else {
			System.out.println("posMao nao encontrada...");
		}

	    return result;		
	}

	public ExpressaoDB getExpressaoDB(String nome) {
		ExpressaoDB result = null;
		Query<ExpressaoDB> listExpr = ofy().query(ExpressaoDB.class).filter("nome", nome);
		if (listExpr.iterator().hasNext()) {
			result = listExpr.iterator().next();
		}

	    return result;		
	}

	public SequenciaExpressaoDB getSequenciaExpressaoDB(String nome) {
		SequenciaExpressaoDB result = null;
		Query<SequenciaExpressaoDB> listSeqExpr = ofy().query(SequenciaExpressaoDB.class).filter("nome", nome);
		if (listSeqExpr.iterator().hasNext()) {
			result = listSeqExpr.iterator().next();
		}

	    return result;		
	}

	public Produto getProdutoByName(String nomeProduto) {
		Produto result = null;
		Query<BuscaProduto> listBusca = ofy().query(BuscaProduto.class).filter("nomeBusca", nomeProduto);
		BuscaProduto resultBusca = null;
		if (listBusca.iterator().hasNext()) {
			resultBusca = listBusca.iterator().next();
			result = getProduto(resultBusca.getIdProduto());
		}

	    return result;
	}

	public LinkCategoria_Produto getLinkCategoria_Produto(String link, String locale) {
		LinkCategoria_Produto result = null;

		System.out.println("Procurando categoria do link:[" +  link + "] no locale: [" + locale + "]");
		Query<LinkCategoria_Produto> listLinkComp = ofy().query(LinkCategoria_Produto.class).filter("link", link).filter("locale", locale);
		if (listLinkComp.iterator().hasNext()) {
			result = listLinkComp.iterator().next();
		} else {
			System.out.println("Procurando por link:[" +  link + "] no locale:[default]");
			Query<LinkCategoria_Produto> listLinkComp2 = ofy().query(LinkCategoria_Produto.class).filter("link", link).filter("locale", "default");
			if (listLinkComp2.iterator().hasNext()) {
				result = listLinkComp2.iterator().next();
			}
		}

	    return result;
	}

	public LinkComparacao getLinkComparacao(String link, SiteHost site) {
		LinkComparacao result = null;

		System.out.println("Procurando por link:[" +  link + "] em " + site.getHost() + "!");
		Query<LinkComparacao> listLinkComp = ofy().query(LinkComparacao.class).filter("link", link).filter("site", site);
		if (listLinkComp.iterator().hasNext()) {
			result = listLinkComp.iterator().next();
		} else {
			System.out.println("Procurando por link:[" +  link + "] em qualquer site!");
			Query<LinkComparacao> listLinkComp2 = ofy().query(LinkComparacao.class).filter("link", link);
			if (listLinkComp2.iterator().hasNext()) {
				result = listLinkComp2.iterator().next();
			}
		}

	    return result;
	}

	public BuscaProduto getBuscaProdutoPorId(Long idBusca) {
		BuscaProduto result = null;
		result = ofy().get(BuscaProduto.class, idBusca);
	    return result;
	}

	public BuscaProduto getBuscaProduto(Long idProduto, String busca) {
		BuscaProduto result = null;
		Query<BuscaProduto> listBusca = ofy().query(BuscaProduto.class).filter("idProduto", idProduto).filter("nomeBusca", busca);
		if (listBusca.iterator().hasNext()) {
			result = listBusca.iterator().next();
		}

	    return result;
	}

	public ArrayList<BuscaProduto> getBuscaProduto(Long idProduto) {
		Query<BuscaProduto> listBusca = ofy().query(BuscaProduto.class).filter("idProduto", idProduto);
	    ArrayList<BuscaProduto> listBuscaTmp = new ArrayList<BuscaProduto>(0);
	    for (BuscaProduto b: listBusca) {
	        listBuscaTmp.add(b);
	    }

	    return listBuscaTmp;
	}

	public ArrayList<Categoria> getListaSubCategorias(Long idCategoriaPai) {
		Query<Categoria> listCategoria = ofy().query(Categoria.class).filter("categoriaPai", idCategoriaPai).order("ordem");
	    ArrayList<Categoria> listCategoriaTmp = new ArrayList<Categoria>(0);
	    for (Categoria hor: listCategoria) {
	        listCategoriaTmp.add(hor);
	    }

	    return listCategoriaTmp;
	}

	/*
	public Horotimo getHorotimo(Long idHorotimo) {
		Horotimo result = null;
	    result = (Horotimo)ofy().get(Horotimo.class, idHorotimo);

	    return result;		
	}

	public PlanoAdesao getPlanoAdesao(Long idPlano) {
		PlanoAdesao result = null;
	    result = (PlanoAdesao)ofy().get(PlanoAdesao.class, idPlano);

	    return result;		
	}

	public FilaProcessamento getUltimoItemFila() {
		FilaProcessamento result = null;
	    //result = (FilaProcessamento)ofy().get(Horotimo.class, idHorotimo);
	    Query<FilaProcessamento> listFila = ofy().query(FilaProcessamento.class).order("-ordem");
	    if (listFila.iterator().hasNext()) {
	    	result = listFila.iterator().next();
	    }
	    return result;
	}

	public void removeItemFila(Long idHorario) {
	    //result = (FilaProcessamento)ofy().get(Horotimo.class, idHorotimo);
	    Query<FilaProcessamento> listFila = ofy().query(FilaProcessamento.class).filter("idHorario", idHorario);
	    for (FilaProcessamento f: listFila) {
	    	//result = listFila.iterator().next();
	    	deleteFila(f.getId());
	    	//listFila.iterator().remove();
	    }
	}

	public ArrayList<Horotimo> getListaHorarios(String status) {
		Query<Horotimo> listHorotimo = ofy().query(Horotimo.class).filter("status", status);
	    ArrayList<Horotimo> listHorotimoTmp = new ArrayList<Horotimo>(0);
	    for (Horotimo hor: listHorotimo) {
	        listHorotimoTmp.add(hor);
	    }

	    return listHorotimoTmp;
	}

	public ArrayList<FilaProcessamento> getFilaHorarios() {
		Query<FilaProcessamento> listFila = ofy().query(FilaProcessamento.class).filter("status", 0).order("-ordem");
	    ArrayList<FilaProcessamento> listFilaTmp = new ArrayList<FilaProcessamento>(0);
	    for (FilaProcessamento f: listFila) {
	        listFilaTmp.add(f);
	    }

	    return listFilaTmp;
	}

	public ArrayList<FilaProcessamento> getFilaHorarios(int numMaximoSalas) {
		Query<FilaProcessamento> listFila = ofy().query(FilaProcessamento.class).filter("status", 0).filter("numSalas", ("<" + numMaximoSalas)).order("-ordem");
	    ArrayList<FilaProcessamento> listFilaTmp = new ArrayList<FilaProcessamento>(0);
	    for (FilaProcessamento f: listFila) {
	        listFilaTmp.add(f);
	    }

	    return listFilaTmp;
	}

	public void deleteFila(Long id) {
		FilaProcessamento result = getFilaHorario(id);
		if (result != null) {
			ofy().delete(result);
		}
	}

	public FilaProcessamento getFilaHorario(Long id) {
		FilaProcessamento result = null;
	    result = (FilaProcessamento)ofy().get(FilaProcessamento.class, id);
	    return result;				
	}
	
	public ArrayList<Horotimo> getListaHorarios(Long idUsuario) {
		Query<Horotimo> listHorotimo = ofy().query(Horotimo.class).filter("idUsuario", idUsuario).order("-idUsuario").order("-date");
	    ArrayList<Horotimo> listHorotimoTmp = new ArrayList<Horotimo>(0);
	    for (Horotimo hor: listHorotimo) {
	        listHorotimoTmp.add(hor);
	    }

	    return listHorotimoTmp;
	}

	public ArrayList<Horotimo> getListaHorariosSemDeletados(Long idUsuario) {
		Query<Horotimo> listHorotimo = ofy().query(Horotimo.class).filter("idUsuario", idUsuario).order("-idUsuario").order("-date");
	    ArrayList<Horotimo> listHorotimoTmp = new ArrayList<Horotimo>(0);
	    for (Horotimo hor: listHorotimo) {
	    	if (hor.getDeletado() == null || hor.getDeletado() == false) {
	    		listHorotimoTmp.add(hor);
	    	}
	    }

	    return listHorotimoTmp;
	}

	public ArrayList<Horotimo> getListaHorariosSemDeletados(Long idUsuario, int offset, int limit) {
		Query<Horotimo> listHorotimo = ofy().query(Horotimo.class).filter("idUsuario", idUsuario).filter("deletado", false).order("-date").order("-idUsuario").offset(offset).limit(limit);
		//Query<Horotimo> listHorotimo = ofy().query(Horotimo.class).offset(offset).limit(limit);
		ArrayList<Horotimo> listHorotimoTmp = new ArrayList<Horotimo>(0);
		for (Horotimo hor: listHorotimo) {
	    	listHorotimoTmp.add(hor);
	    }

	    return listHorotimoTmp;
	}

	public ArrayList<Horotimo> getListaHorariosPorID(Long idHorario) {
		Query<Horotimo> listHorotimo = ofy().query(Horotimo.class).filter("id", idHorario).order("-idUsuario").order("-date");
	    ArrayList<Horotimo> listHorotimoTmp = new ArrayList<Horotimo>(0);
	    for (Horotimo hor: listHorotimo) {
	        listHorotimoTmp.add(hor);
	    }

	    return listHorotimoTmp;
	}
	
	public ArrayList<Horotimo> getListaHorarios(int offset, int limit) {
		Query<Horotimo> listHorotimo = ofy().query(Horotimo.class).order("-date").order("-idUsuario").offset(offset).limit(limit);
		//Query<Horotimo> listHorotimo = ofy().query(Horotimo.class).offset(offset).limit(limit);
	    ArrayList<Horotimo> listHorotimoTmp = new ArrayList<Horotimo>(0);
	    for (Horotimo hor: listHorotimo) {
	        listHorotimoTmp.add(hor);
	    }

	    return listHorotimoTmp;
	}
	*/

	public ArrayList<Usuario> getListaUsuarios(String[] campo, Object[] filtro, String[] tipoDado, int offset, int limit, String[] orderBy) {

		Query<Usuario> listUsuario = ofy().query(Usuario.class);
		System.out.println("sem filtro: size:" + listUsuario.count());
		
		for (int i = 0; i < campo.length; i++) {
			System.out.println("campo[" + i + "] = " + campo[i]);
			System.out.println("valor[" + i + "] = " + filtro[i]);
			System.out.println("tipoDado[" + i + "] = " + tipoDado[i]);
			
			if (tipoDado[i].equals("boolean")) {
				listUsuario = listUsuario.filter(campo[i], ((Boolean)filtro[i]).booleanValue());
				System.out.println("Filtrou boolean...");
			} else if (tipoDado[i].equals("string")) {
				listUsuario = listUsuario.filter(campo[i], ((String)filtro[i]).toString());
				System.out.println("Filtrou string...");
			} else if (tipoDado[i].equals("int")) {
				listUsuario = listUsuario.filter(campo[i], ((Integer)filtro[i]).intValue());
				System.out.println("Filtrou int...");
			}
			
			
			System.out.println("primeiro filtro: size:" + listUsuario.count());

		}
		System.out.println("primeiro filtro final: size:" + listUsuario.count());

		listUsuario = listUsuario.offset(offset).limit(limit);
		System.out.println("segundo filtro: offset e limite size:" + listUsuario.count());

		for (int i = 0; i < orderBy.length; i++) {
			listUsuario = listUsuario.order(orderBy[i]);
		}
		System.out.println("order by: size:" + listUsuario.count());

		ArrayList<Usuario> listUsuarioTmp = new ArrayList<Usuario>(0);
	    for (Usuario u: listUsuario) {
	        listUsuarioTmp.add(u);
	    }

	    return listUsuarioTmp;
	}

	public ArrayList<Usuario> getListaUsuarios(int offset, int limit) {
		Query<Usuario> listUsuario = ofy().query(Usuario.class).offset(offset).limit(limit);

		ArrayList<Usuario> listUsuarioTmp = new ArrayList<Usuario>(0);
	    for (Usuario u: listUsuario) {
	        listUsuarioTmp.add(u);
	    }

	    return listUsuarioTmp;
	}

	public ArrayList<Usuario> getListaUsuariosNaoConfirmados(int numEmailReenvios, int limite) {
		Query<Usuario> listUsuario;
		
		listUsuario = ofy().query(Usuario.class).filter("usuarioConfirmado", false).order("-date");

		int countLimite = 1;
		
		ArrayList<Usuario> listUsuarioTmp = new ArrayList<Usuario>(0);
	    for (Usuario u: listUsuario) {

	    	System.out.println("u.getNome() = " + u.getNomeUsuario() + ", " + u.getNumReenviosEmail());
	    	if (u.getNumReenviosEmail() == numEmailReenvios || numEmailReenvios < 0) {
	    		listUsuarioTmp.add(u);
	    	    if (limite > 0) {
	    	    	countLimite++;
	    	    }
	    	    if (countLimite > limite && limite > 0) {
	    	    	break;
	    	    }
	    	}
	    }
	    
	    return listUsuarioTmp;
	}
	
	/*
	public ArrayList<Horotimo> getListaHorarios(Long idUsuario, int offset, int limit) {
		
		Query<Horotimo> listHorotimo = ofy().query(Horotimo.class);
		if (!idUsuario.equals(0L)) {
			listHorotimo = listHorotimo.filter("idUsuario", idUsuario);
		}
		if (offset != 0) {
			listHorotimo = listHorotimo.offset(offset);
		}
		if (limit != 0) {
			listHorotimo = listHorotimo.limit(limit);
		}
		
		listHorotimo = listHorotimo.order("-date").order("-idUsuario");
	    
		ArrayList<Horotimo> listHorotimoTmp = new ArrayList<Horotimo>(0);
	    for (Horotimo hor: listHorotimo) {
	        listHorotimoTmp.add(hor);
	    }

	    return listHorotimoTmp;
	}
	
	public ArrayList<PlanoAdesao> getListaPlanos() {
	    ArrayList<PlanoAdesao> listPlanoTmp = new ArrayList<PlanoAdesao>(0);
	    Query<PlanoAdesao> listPlano = ofy().query(PlanoAdesao.class).order("ordem");

	    for (PlanoAdesao p: listPlano) {
	    	System.out.println("plano carregado");
	        listPlanoTmp.add(p);
	    }

	    
	    //while(listPlano.iterator().hasNext()) {
	    //	System.out.println("Carregando plano...");
	    //	listPlanoTmp.add((PlanoAdesao)listPlano.iterator().next());
	    //}
	    
	    return listPlanoTmp;
		
	}

	public ArrayList<PlanoAdesao> getListaPlanos(Integer filtroNumSalas) {
	    ArrayList<PlanoAdesao> listPlanoTmp = new ArrayList<PlanoAdesao>(0);
	    System.out.println("Buscando plano para cobrar...NumSalas = " + filtroNumSalas);
	    Query<PlanoAdesao> listPlano = ofy().query(PlanoAdesao.class).filter("numMinimoSalas <=", String.valueOf(filtroNumSalas)).order("numMinimoSalas").order("ordem");

	    for (PlanoAdesao p: listPlano) {
	    	if (p.getNumMaximoSalas() >= filtroNumSalas) {
	    		System.out.println("plano carregado");
	    		listPlanoTmp.add(p);
	    	}
	    }

	    return listPlanoTmp;
	}
	*/
	
	public Usuario getUsuario(String emailOuId) {
		Usuario result = null;

		if (emailOuId.indexOf("@") != -1) {
			System.out.println("buscando pelo email...");
			Iterable<Usuario> listUsuario = ofy().query(Usuario.class).filter("email", emailOuId);

			if (listUsuario.iterator().hasNext()) {
				System.out.println("achou usuario...");
				result = (Usuario)listUsuario.iterator().next(); 
			} else {
				System.out.println("nao achou usuario...");
			}

		} else if (Util.isNumeric(emailOuId)) {
			System.out.println("buscando pelo id...");
			long uId = Long.parseLong(emailOuId);
			try {
				result = ofy().get(Usuario.class, uId);
			} catch (com.googlecode.objectify.NotFoundException e1) {
				// não encontrado.
			} catch (java.lang.IllegalArgumentException e2) {
				// ilegal
			}
		}
		
		if (result == null) {
			Iterable<Usuario> listUsuario = ofy().query(Usuario.class).filter("userId", emailOuId);

			if (listUsuario.iterator().hasNext()) {
				System.out.println("achou usuario...");
				result = (Usuario)listUsuario.iterator().next(); 
			} else {
				System.out.println("nao achou usuario...");
			}
		}

		//System.out.println("result = null?" + (result == null));
		return result;		
	}

	public Usuario getUsuarioFB(String userId) {
		Usuario result = null;

		Iterable<Usuario> listUsuario = ofy().query(Usuario.class).filter("userId", userId).filter("origemLogin", OrigemLogin.FACEBOOK.getSiteOrigem());

		if (listUsuario.iterator().hasNext()) {
			result = (Usuario)listUsuario.iterator().next(); 
		}

		return result;		
	}

	public Usuario getUsuarioTwitter(String userId) {
		Usuario result = null;

		Iterable<Usuario> listUsuario = ofy().query(Usuario.class).filter("userId", userId).filter("origemLogin", OrigemLogin.TWITTER.getSiteOrigem());

		if (listUsuario.iterator().hasNext()) {
			result = (Usuario)listUsuario.iterator().next(); 
		}

		return result;		
	}

	public Usuario getUsuario(Long idUsuario) {
		Usuario result = null;
		try {
			result = (Usuario)ofy().get(Usuario.class, idUsuario);
		} catch (com.googlecode.objectify.NotFoundException e) {
			System.out.println("Usuario nao encontrado com o id: " + idUsuario);
		}

	    return result;		
	}
	
	public Email getEmail(Long idEmail) {
		Email result = null;
		try {
			result = (Email)ofy().get(Email.class, idEmail);
		} catch (com.googlecode.objectify.NotFoundException e) {
			System.out.println("Email nao encontrado com o id: " + idEmail);
		}

	    return result;		
	}

	public ArrayList<Usuario> getListUsuario(String emailOuId) {

		ArrayList<Usuario> listUsuarioTmp = new ArrayList<Usuario>(0);
		if (emailOuId.indexOf("@") != -1) {

			Query<Usuario> listUsuario = ofy().query(Usuario.class).filter("email", emailOuId);

			for (Usuario u: listUsuario) {
				System.out.println("teste3.1");
				listUsuarioTmp.add(u);
			}

		} else if (Util.isNumeric(emailOuId)) {
			long uId = Long.parseLong(emailOuId);
			Usuario u = ofy().get(Usuario.class, uId);

			listUsuarioTmp.add(u);
		}
	    return listUsuarioTmp;
	}

	public ArrayList<Usuario> getListUsuario() {
		Query<Usuario> listUsuario = ofy().query(Usuario.class);
	    ArrayList<Usuario> listUsuarioTmp = new ArrayList<Usuario>(0);
	    for (Usuario u: listUsuario) {
	        listUsuarioTmp.add(u);
	    }
	    return listUsuarioTmp;
	}

	public ArrayList<Usuario> getListUsuario(int offset, int limit) {
		Query<Usuario> listUsuario = ofy().query(Usuario.class).offset(offset).limit(limit);
	    ArrayList<Usuario> listUsuarioTmp = new ArrayList<Usuario>(0);
	    for (Usuario u: listUsuario) {
	        listUsuarioTmp.add(u);
	    }
	    return listUsuarioTmp;
	}

	public boolean gravaNovoUsuario(Usuario u) {
		boolean result = false;
		Objectify ofy = ObjectifyService.beginTransaction();
		try {
			System.out.println("teste1...");
			ofy().put(u);
			System.out.println("teste2...");
			ofy.getTxn().commit();
			System.out.println("teste3...");
			result = true;
			System.out.println("teste4...");
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (ofy.getTxn().isActive()) {
				System.out.println("teste5...");
				ofy.getTxn().rollback(); 
				System.out.println("teste6...");
				result = false;
			}
		}

		System.out.println("result = " + result);
		return result;
	}

	public boolean salvaLinkBlogComparacao(Long idComparacao, Long idUsuarioLink, String nomeBlog, String link) {
		boolean result = false;

		Comparacao comp = getComparacao(idComparacao);
		if (comp != null) {
			if (nomeBlog.equals("") && link.equals("")) {
				comp.setIdUsuarioLink(0L);
				comp.setNomeBlog(nomeBlog);
				comp.setLinkBlog(link);
				comp.setDiasCheckLink(0);
			} else {
				comp.setIdUsuarioLink(idUsuarioLink);
				comp.setNomeBlog(nomeBlog);
				comp.setLinkBlog(link);
				comp.setDiasCheckLink(-1); //ativo mas irá checar pra ver se está ok
			}
			result = gravaNovaComparacao(comp);
			gravaNovoEmail(new Email(new String[]{"rodteixo2@yahoo.com.br"}, "QUAL O MELHOR - NOVO LINK", "Comp: " + comp.getId() + ", comp pergunta: " + comp.getPergunta(comp.getSiteOriginal(), comp.getLocale()) + ", comp site: " + comp.getSiteOriginal().getHost() + ", link: [" + comp.getLinkBlog() + "]", "text/plain", new Date()));
		}

		return result;
	}

	public boolean salvaCategoriaProduto(Long idProduto, Long idCategoria) {
		boolean result = false;

		Produto p = getProduto(idProduto);
		if (p != null) {
			p.setIdCategoria(idCategoria);
			result = gravaNovoProduto(p);
		}

		return result;
	}
	/*
	public boolean gravaNovoHorotimo(Horotimo hor) {
		boolean result = false;
		Objectify ofy = ObjectifyService.beginTransaction();
		try {
			hor.setDate(new Date());
			ofy.put(hor);
			ofy.getTxn().commit();
			result = true;
		} finally {
			if (ofy.getTxn().isActive()) { 
				ofy.getTxn().rollback(); 
			}
		}
		
		return result;
	}
	
	public boolean gravaNovaFila(FilaProcessamento f) {
		Objectify ofy = ObjectifyService.beginTransaction();
		try {		
			ofy.put(f);
			ofy.getTxn().commit();
		} finally {
			if (ofy.getTxn().isActive()) { 
				ofy.getTxn().rollback(); 
			}
		}
		
		return true;
	}
	
	public boolean gravaNovoPlano(PlanoAdesao p) {
		Objectify ofy = ObjectifyService.beginTransaction();
		try {		
			ofy.put(p);
			ofy.getTxn().commit();
		} finally {
			if (ofy.getTxn().isActive()) { 
				ofy.getTxn().rollback(); 
			}
		}
		
		return true;
	}
	*/

	public boolean gravaNovoEmail(Email e) {
		Objectify ofy = ObjectifyService.beginTransaction();
		boolean result = false;
		try {		
			ofy.put(e);
			ofy.getTxn().commit();
			result = true;
		} finally {
			if (ofy.getTxn().isActive()) { 
				ofy.getTxn().rollback(); 
			}
		}
		return result;
	}

	public boolean gravaNovoTermoIdioma(TermoIdioma t) {
		Objectify ofy = ObjectifyService.beginTransaction();
		boolean result = false;
		try {		
			ofy.put(t);
			ofy.getTxn().commit();
			result = true;
		} finally {
			if (ofy.getTxn().isActive()) { 
				ofy.getTxn().rollback(); 
			}
		}
		return result;
	}

	public boolean gravaNovoLinkCategoria_Produto(LinkCategoria_Produto l, boolean useTransaction) {
		Objectify ofy = ObjectifyService.beginTransaction();
		boolean result = false;
		if (useTransaction) {
			try {		
				ofy.put(l);
				ofy.getTxn().commit();
				result = true;
			} finally {
				if (ofy.getTxn().isActive()) { 
					ofy.getTxn().rollback(); 
				}
			}
		} else {
			ofy().put(l);
			result = true;
		}
		return result;
	}

	public boolean gravaNovoLinkComparacao(LinkComparacao l, boolean useTransaction) {
		Objectify ofy = ObjectifyService.beginTransaction();
		boolean result = false;
		if (useTransaction) {
			try {		
				ofy.put(l);
				ofy.getTxn().commit();
				result = true;
			} finally {
				if (ofy.getTxn().isActive()) { 
					ofy.getTxn().rollback(); 
				}
			}
		} else {
			ofy().put(l);
			result = true;
		}
		return result;
	}
												 // key = locale, valor = nome da categoria traduzido
	public boolean gravaNovaCategoria(Categoria cat, HashMap<String, String> mapLocale_Nome) {
		Objectify ofy = ObjectifyService.beginTransaction();
		boolean novaCategoria = (cat.getId() == null || cat.getId() == 0);
		boolean result = false;
		try {
			if (mapLocale_Nome == null) {
				mapLocale_Nome = cat.getLocale_Name();
			}

			Iterator<Entry<String, String>> it = mapLocale_Nome.entrySet().iterator();
			System.out.println("GRAVANDO NOVA CATEGORIA! Map Locales.SIZE = " + mapLocale_Nome.entrySet().size());
			while (it.hasNext()) {
				Entry<String, String> entry = it.next();
				System.out.println("locale = " + entry.getKey() + ", nomeTraduzido = " + entry.getValue());
			}

			cat.setMapPath_Name(getFullLinkCategoria(cat, mapLocale_Nome)); //retornar o path e o nome da categoria a ser gravada, respeitando os locales passados
			ofy.put(cat);
			ofy.getTxn().commit();

			//atualiza os links da categoria
			if (!novaCategoria) {
				System.out.println("Deletando links categoria: " + cat.getId());
				deletaTodosLinksCategoria(cat.getId());
				System.out.println("Links Deletados!");
			}

			System.out.println("gravando link da categoria..");
			Iterator<Entry<String, String[]>> it2 = cat.getMapPath().entrySet().iterator();
			System.out.println("GRAVANDO NOVA CATEGORIA! Map Locales.SIZE = " + cat.getMapPath().entrySet().size());
			while (it2.hasNext()) {
				Entry<String, String[]> entry = it2.next();
				LinkCategoria_Produto link = new LinkCategoria_Produto(entry.getValue()[0], cat.getId(), 0L, entry.getKey());
				System.out.println("vai gravar o link:" + link.getLink());
				gravaNovoLinkCategoria_Produto(link, true);
				System.out.println("link gravado!");
			}

			result = true;
			getListaCategoriasNivel0(true);   //atualiza o memcache
		} finally {
			if (ofy.getTxn().isActive()) { 
				ofy.getTxn().rollback(); 
			}
		}
		return result;
	}

	public boolean gravaNovoProduto(Produto p) {
		Objectify ofy = ObjectifyService.beginTransaction();
		boolean result = false;
		boolean novoProduto = (p.getId() == null || p.getId() == 0);
		try {
			Categoria cat;
			if (p.getIdCategoria() == 0) {
				cat = getCategoriaByName("PENDENTE");
				p.setIdCategoria(cat.getId());
			} else {
				cat = getCategoria(p.getIdCategoria());
			}
			System.out.println("Categoria do produto: " + cat.getNomeCategoria() + " mapPath.size:" + cat.getMapPath().size());
			//p.setPath(getFullLinkCategoria(cat) + "/" + Util.converteEmLink(p.getNomeProduto()));
			ofy.put(p);

			if (!novoProduto) {
				deletaTodasBuscasProduto(p.getId());
				System.out.println("Deletando links do produto: " + p.getId());
				deletaTodosLinksProduto(p.getId());
				System.out.println("Links Deletados!");
			}

			for (int i = 0; i < p.getListBusca().size(); i++) {
				BuscaProduto bsc = new BuscaProduto(p.getListBusca().get(i), p.getId());
				gravaNovaBuscaProduto(bsc, false);
			}

			ofy.getTxn().commit();
			result = true;

			System.out.println("gravando link do produto..:" + p.getId() + ", [" + p.getNomeProduto() + "]");
			Iterator<Entry<String, String[]>> it2 = cat.getMapPath().entrySet().iterator();
			while (it2.hasNext()) {
				Entry<String, String[]> entry = it2.next();
				LinkCategoria_Produto link = new LinkCategoria_Produto(entry.getValue()[0] + "/" + Util.converteEmLink(p.getNomeProduto()), 0L, p.getId(), entry.getKey());
				System.out.println("vai gravar o link:" + link.getLink());
				gravaNovoLinkCategoria_Produto(link, true);
				System.out.println("link gravado!");
			}

		} finally {
			if (ofy.getTxn().isActive()) { 
				ofy.getTxn().rollback(); 
			}
		}
		return result;
	}

	public boolean gravaNovaPosicaoMaoDB(PosicaoMaosDB pMaoDB) {
		Objectify ofy = ObjectifyService.beginTransaction();
		boolean result = false;
		try {		
			ofy.put(pMaoDB);
			ofy.getTxn().commit();
			result = true;
		} finally {
			if (ofy.getTxn().isActive()) { 
				ofy.getTxn().rollback(); 
			}
		}
		return result;
	}

	public boolean gravaNovaExpressaoDB(ExpressaoDB exprDB) {
		Objectify ofy = ObjectifyService.beginTransaction();
		boolean result = false;
		try {		
			ofy.put(exprDB);
			ofy.getTxn().commit();
			result = true;
		} finally {
			if (ofy.getTxn().isActive()) { 
				ofy.getTxn().rollback(); 
			}
		}
		return result;
	}

	public boolean gravaNovaSequenciaExpressaoDB(SequenciaExpressaoDB seqExprDB) {
		Objectify ofy = ObjectifyService.beginTransaction();
		boolean result = false;
		try {		
			ofy.put(seqExprDB);
			ofy.getTxn().commit();
			result = true;
		} finally {
			if (ofy.getTxn().isActive()) { 
				ofy.getTxn().rollback(); 
			}
		}
		return result;
	}

	public boolean gravaNovaParteAvatar(ParteAvatar p) {
		Objectify ofy = ObjectifyService.beginTransaction();
		boolean result = false;
		try {			
			ofy.put(p);
			ofy.getTxn().commit();
			result = true;
		} finally {
			if (ofy.getTxn().isActive()) { 
				ofy.getTxn().rollback(); 
			}
		}
		return result;
	}

	public boolean gravaAtualizacaoComparacao(Comparacao c) {
		//Grava a comparacao sem mexer em links
		Objectify ofy = ObjectifyService.beginTransaction();
		boolean result = false;

		try {
			ofy.put(c);
			ofy.getTxn().commit();
			result = true;

		} finally {
			if (ofy.getTxn().isActive()) { 
				ofy.getTxn().rollback(); 
			}
		}
		return result;
	}

	public boolean gravaNovaComparacao(Comparacao c) {
		Objectify ofy = ObjectifyService.beginTransaction();
		boolean novaComparacao = (c.getId() == null || c.getId() == 0);
		boolean result = false;

		try {

			if (!novaComparacao) {
				System.out.println("Deletando links: " + c.getId());
				deletaTodosLinksComparacao(c.getId());
				System.out.println("Links Deletados!");
				deletaTodasBuscasComparacao(c.getId());
				System.out.println("Buscas Comparacoes deletadas!");

			} else {

				//Adiciona email
				Email e = new Email(new String[]{"rodteixo2@yahoo.com.br"}, "QUAL O MELHOR - NOVA COMPARACAO CRIADA!", "Comparacao: " + c.getPergunta(c.getSiteOriginal(), c.getLocale()) + "\r\nSite:" + c.getSiteOriginal().getHost(), "text/plain", new Date());
				gravaNovoEmail(e);

				//Criar a imagem da comparacao versus
				if (c.getTipoComparacao() == TipoComparacao.TIPO_COMPARACAO_2_PRODUTOS) {
					//grava img versus
					gravaLinkImageVersus(c, false);
				}
			}

			ofy.put(c);
			ofy.getTxn().commit();
			result = true;

			System.out.println("c.getListPathComparacao().size() = " + c.getListPathComparacao().size());
			System.out.println("c.getId = " + c.getId());
			System.out.println("result = " + result);
			for (int i = 0; i < c.getListPathComparacao().size(); i++) {
				LinkComparacao link = new LinkComparacao(c.getListPathComparacao().get(i).getPath(), c.getId(), c.getListPathComparacao().get(i).getSite());
				System.out.println("vai gravar o link:" + link.getLink());
				gravaNovoLinkComparacao(link, true);
				System.out.println("link gravado!");
			}

			//Grava a busca comparacao - RELACIONA CADA PRODUTO A ESTA COMPARACAO
			System.out.println("Salvando Busca Comparacao listProds.size() = " + c.getListProdutosComp().size());
			for (Long idProd: c.getListProdutosComp()) {
				if (idProd != null) {
					System.out.println("Vai gravar a busca comparacao: idProd: " + idProd);
					boolean res = gravaNovaBuscaComparacao(new BuscaComparacao(c.getId(), idProd), true);
					if (res) {
						System.out.println("Busca comparacao SALVA COM SUCESSO! idProd: " + idProd);	
					} else {
						System.out.println("Busca comparacao FALHOU! idProd: " + idProd);
					}
				}
			}

		} finally {
			if (ofy.getTxn().isActive()) { 
				ofy.getTxn().rollback(); 
			}
		}
		return result;
	}

	public boolean gravaNovaBuscaProduto(BuscaProduto b, boolean useTransaction) {
		boolean result = false;
		if (useTransaction) {
			Objectify ofy = ObjectifyService.beginTransaction();

			try {
				ofy.put(b);
				ofy.getTxn().commit();
				result = true;
			} finally {
				if (ofy.getTxn().isActive()) { 
					ofy.getTxn().rollback(); 
				}
			}
		} else {
			ofy().put(b);
			result = true;
		}
		return result;
	}

	public boolean gravaNovaBuscaComparacao(BuscaComparacao b, boolean useTransaction) {
		boolean result = false;
		if (useTransaction) {
			Objectify ofy = ObjectifyService.beginTransaction();

			try {
				ofy.put(b);
				ofy.getTxn().commit();
				result = true;
			} finally {
				if (ofy.getTxn().isActive()) { 
					ofy.getTxn().rollback(); 
				}
			}
		} else {
			ofy().put(b);
			result = true;
		}
		return result;
	}

	public long gravaNovoLinkBlobImage(LinkBlobImage lbi, boolean useTransaction) {
		long result = 0L;
		if (useTransaction) {
			Objectify ofy = ObjectifyService.beginTransaction();

			try {
				ofy.put(lbi);
				ofy.getTxn().commit();
				result = lbi.getId();
			} finally {
				if (ofy.getTxn().isActive()) { 
					ofy.getTxn().rollback(); 
				}
			}
		} else {
			ofy().put(lbi);
			result = lbi.getId();
		}
		return result;
	}

	public String getFullLinkCategoria(Categoria c) {
		String result = "";
		if (c.getCategoriaPai() != null) {
			result = getFullLinkCategoria(getCategoria(c.getCategoriaPai()));
		}

		return result + "/" + ClientUtils.converteEmLink(c.getNomeCategoria()); 
	}

	public HashMap<String, String[]> getFullLinkCategoria(Categoria c, HashMap<String, String> mapLocale_Name) {
		HashMap<String, String[]> mapResult = new HashMap<String, String[]>(0);
		String result = "";

		Iterator<Entry<String, String>> it = mapLocale_Name.entrySet().iterator();
		while (it.hasNext()) {
			Entry<String, String> entry = it.next();
			String locale = entry.getKey();
			String name = entry.getValue();

			if (c.getCategoriaPai() != null) {
				result = getFullLinkCategoria(getCategoria(c.getCategoriaPai()), locale);
			}

			String resFinal = result + "/" + Util.converteEmLink(mapLocale_Name.get(locale));
			while (resFinal.indexOf("//") != -1) {
				System.out.println("resFinal = " + resFinal);
				resFinal = resFinal.replaceAll("//", "/");
			}

			mapResult.put(locale, new String[]{resFinal, name});
			System.out.println("adicionando mapResult! locale = " + locale + ", path = " + mapResult.get(locale)[0] + ", nome = " + mapResult.get(locale)[1]);
		}

		return mapResult;  
	}

	public String getFullLinkCategoria(Categoria c, String locale) {
		String result = "";
		if (c.getCategoriaPai() != null) {
			result = getFullLinkCategoria(getCategoria(c.getCategoriaPai()), locale);
		}

		return result + "/" + Util.converteEmLink(c.getPathCategoria(locale)); 
	}

	public ArrayList<Email> getListaEmailPendente(int offset, int limit) {
		Query<Email> listEmail = ofy().query(Email.class).filter("enviado", false).offset(offset).limit(limit);

		ArrayList<Email> listEmailTmp = new ArrayList<Email>(0);
	    for (Email u: listEmail) {
	        listEmailTmp.add(u);
	    }

	    return listEmailTmp;
	}

	public ArrayList<Email> getListaEmailEnviados(int offset, int limit) {
		Query<Email> listEmail = ofy().query(Email.class).filter("enviado", true).offset(offset).limit(limit);

		ArrayList<Email> listEmailTmp = new ArrayList<Email>(0);
	    for (Email u: listEmail) {
	        listEmailTmp.add(u);
	    }

	    return listEmailTmp;
	}

	public boolean gravaNovoSistema(ParametrosSistema ps) {
		Objectify ofy = ObjectifyService.beginTransaction();
		try {		
			ofy.put(ps);
			ofy.getTxn().commit();
		} finally {
			if (ofy.getTxn().isActive()) { 
				ofy.getTxn().rollback(); 
			}
		}
		
		return true;
	}

	public boolean deletaCategoria(Long idCategoria) {
		boolean result = false;
		Categoria cat = getCategoria(idCategoria);
		if (cat != null) {
			ofy().delete(cat);
			result = true;
		}
		return result;
	}

	public boolean deletaBuscaComparacao(BuscaComparacao bsc) {
		boolean result = false;
		if (bsc != null) {
			ofy().delete(bsc);
			result = true;
		}
		return result;
	}

	public boolean deletaLinkBlogImage(LinkBlobImage lbi) {
		boolean result = false;
		if (lbi != null) {
			ofy().delete(lbi);
			result = true;
		}
		return result;
	}

	public boolean deletaProduto(Long idProduto) {
		boolean result = false;
		Produto prod = getProduto(idProduto);
		if (prod != null) {
			ofy().delete(prod);
			//deleta as buscas, comparacoes e links envolvidas neste produto 
			deletaTodasBuscasProduto(idProduto);

			ArrayList<BuscaComparacao> listBusca = getListaBuscaComparacao(idProduto, null);
			for (BuscaComparacao bsc: listBusca) {
				result = result && deletaBuscaComparacao(bsc);
				result = result && deletaComparacao(bsc.getIdComparacao());
			}

			result = true;
		}
		return result;
	}

	public boolean deletaBuscaProduto(Long idProduto, String busca) {
		boolean result = false;
		BuscaProduto buscaProd = getBuscaProduto(idProduto, busca);
		if (buscaProd != null) {
			ofy().delete(buscaProd);
			result = true;
		}
		return result;
	}

	public boolean deletaBuscaProduto(Long idBusca) {
		boolean result = false;
		BuscaProduto buscaProd = getBuscaProdutoPorId(idBusca);
		if (buscaProd != null) {
			ofy().delete(buscaProd);
			result = true;
		}
		return result;
	}

	public boolean deletaLinkComparacao(Long idLink) {
		boolean result = false;
		LinkComparacao link = getLinkComparacao(idLink);
		if (link != null) {
			ofy().delete(link);
			result = true;
		}
		return result;
	}

	public boolean deletaLinkComparacao(LinkComparacao link) {
		boolean result = false;
		if (link != null) {
			ofy().delete(link);
			result = true;
			System.out.println("deletou o link: " + link.getLink() + "_" + link.getSite().getHost());
		}
		return result;
	}

	public boolean deletaLinkCategoria_Produto(LinkCategoria_Produto link) {
		boolean result = false;
		if (link != null) {
			ofy().delete(link);
			result = true;
			System.out.println("deletou o link: " + link.getLink() + "_" + link.getLocale());
		}
		return result;
	}

	public boolean deletaTermoIdioma(Long id) {
		boolean result = false;
		TermoIdioma termoIdioma = getTermoIdioma(id);
		if (termoIdioma != null) {
			ofy().delete(termoIdioma);
			result = true;
		}
		return result;
	}

	public boolean deletaPosicaoMaoDB(String nome) {
		boolean result = false;
		PosicaoMaosDB pM = getPosicaoMaoDB(nome);
		if (pM != null) {
			ofy().delete(pM);
			result = true;
		} else {
			System.out.println("pM is null...");
		}
		return result;
	}

	public boolean deletaExpressaoDB(String nome) {
		boolean result = false;
		ExpressaoDB expr = getExpressaoDB(nome);
		if (expr != null) {
			ofy().delete(expr);
			result = true;
		}
		return result;
	}

	public boolean deletaComparacao(Long idComparacao) {
		boolean result = false;
		Comparacao comp = getComparacao(idComparacao);
		if (comp != null) {
			ofy().delete(comp);
			result = true;
			// Deletar a buscaComparacao
			ArrayList<BuscaComparacao> listBusca = getListaBuscaComparacao(idComparacao);
			for (BuscaComparacao bsc: listBusca) {
				result = result && deletaBuscaComparacao(bsc);
			}
		}
		return result;
	}

	public boolean deletaPathComparacao(Long idComp, SiteHost site) {
		boolean result = false;
		boolean encontrado = false;
		Comparacao comp = getComparacao(idComp);
		for (int i = 0; i < comp.getListPathComparacao().size(); i++) {
			if (comp.getListPathComparacao().get(i).getSite().equals(site)) {
				comp.getListPathComparacao().remove(i);
				encontrado = true;
				break;
			}
		}

		if (encontrado) {
			result = gravaNovaComparacao(comp);
		}
		return result;		
	}

	public boolean deletaTodasBuscasProduto(Long idProd) {
		boolean result = true;

		ArrayList<BuscaProduto> listBusca = getBuscaProduto(idProd);
		for (int i = 0; i < listBusca.size(); i++) {
			result = result && deletaBuscaProduto(listBusca.get(i).getId());
		}

		return result;
	}

	public boolean deletaTodasBuscasComparacao(Long idComparacao) {
		boolean result = true;

		ArrayList<BuscaComparacao> listBusca = getListaBuscaComparacao(idComparacao);
		for (int i = 0; i < listBusca.size(); i++) {
			result = result && deletaBuscaComparacao(listBusca.get(i));
		}

		return result;
	}

	public boolean deletaTodosLinksComparacao(Long idComp) {
		boolean result = true;

		ArrayList<LinkComparacao> listLink = getListaLinkComparacao(idComp);
		System.out.println("Numero de links a serem deletados = " + listLink.size());
		for (LinkComparacao link: listLink) {
			//result = result && deletaBuscaProduto(listLink.get(i).getId());
			result = result && deletaLinkComparacao(link);
		}

		return result;
	}

	public boolean deletaTodosLinksCategoria(Long idCategoria) {
		boolean result = true;

		ArrayList<LinkCategoria_Produto> listLink = getListaLinkCategoria(idCategoria);
		System.out.println("Numero de links a serem deletados = " + listLink.size());
		for (LinkCategoria_Produto link: listLink) {
			//result = result && deletaBuscaProduto(listLink.get(i).getId());
			result = result && deletaLinkCategoria_Produto(link);
		}

		return result;
	}

	public boolean deletaTodosLinksProduto(Long idProduto) {
		boolean result = true;

		ArrayList<LinkCategoria_Produto> listLink = getListaLinkProduto(idProduto);
		System.out.println("Numero de links a serem deletados = " + listLink.size());
		for (LinkCategoria_Produto link: listLink) {
			//result = result && deletaBuscaProduto(listLink.get(i).getId());
			result = result && deletaLinkCategoria_Produto(link);
		}

		return result;
	}

	public boolean deletaLocaleCategoria(Long idCategoria, String locale) {
		boolean result = false;
		boolean encontrado = false;
		Categoria cat = getCategoria(idCategoria);

		if (cat.getMapPath().containsKey(locale)) {
			cat.getMapPath().remove(locale);
			encontrado = true;
		}

		if (encontrado) {
			result = gravaNovaCategoria(cat, null);
		}
		return result;		
	}

	public boolean deletaBusca(Long idProd, String busca) {
		boolean result = false;
		boolean encontrado = false;
		Produto prod = getProduto(idProd);
		for (int i = 0; i < prod.getListBusca().size(); i++) {
			if (prod.getListBusca().get(i).equals(busca)) {
				prod.getListBusca().remove(i);
				
				//deletaBuscaProduto(idProd, busca);
				encontrado = true;
				break;
			}
		}

		if (encontrado) {
			result = gravaNovoProduto(prod);
		}
		return result;		
	}

	public boolean addBusca(Long idProduto, String busca) {
		boolean result = false;
		Produto prod = getProduto(idProduto);
		if (prod != null) {
			prod.getListBusca().add(busca);
			result = gravaNovoProduto(prod);

			//if (result) {
			//	BuscaProduto bsc = new BuscaProduto(busca, idProduto);
			//	gravaNovaBuscaProduto(bsc);
			//	System.out.println("nova busca id = " + bsc.getId());
			//}
		}

		return result;		
	}

	public boolean addLocaleCategoria(Long idCategoria, String locale, String nomeTraduzido) {
		boolean result = false;
		Categoria cat = getCategoria(idCategoria);
		if (cat != null) {
			HashMap<String, String> mapLocale_Name = cat.getLocale_Name();
			mapLocale_Name.put(locale, nomeTraduzido);
			result = gravaNovaCategoria(cat, mapLocale_Name);
		}

		return result;		
	}

	public Comparacao addPathComparacao(Long idComp, String path, SiteHost site, String complementoPergunta) {
		Comparacao result = null;
		Comparacao comp = getComparacao(idComp);
		if (comp != null) {
			comp.getListPathComparacao().add(new PathComparacao(path, site, complementoPergunta));
			boolean res = gravaNovaComparacao(comp);
			if (res) {
				result = comp;
			}
		}

		return result;		
	}

	public boolean deletaParteAvatar(Long idParteAvatar) {
		boolean result = false;
		ParteAvatar p = getParteAvatar(idParteAvatar);
		if (p != null) {
			ofy().delete(p);
			result = true;
		}
		return result;
	}

	public String gravaLinkImageVersus(Comparacao c, boolean salvar) {

		String result = "Erro";

		if (c.getTipoComparacao() == TipoComparacao.TIPO_COMPARACAO_2_PRODUTOS) {

			ImagesService imagesService = ImagesServiceFactory.getImagesService();

			Produto p1 = getProduto(c.getListProdutosComp().get(0));
			Produto p2 = getProduto(c.getListProdutosComp().get(1));

			if (
					(p1.getListEnderecoFoto() != null && p1.getListEnderecoFoto().size() > 0 && p1.getListEnderecoFoto().get(0) != null)
					&&
					(p2.getListEnderecoFoto() != null && p2.getListEnderecoFoto().size() > 0 && p2.getListEnderecoFoto().get(0) != null)
				) {

				try {

					String url1 = ((p1.getListEnderecoFoto().get(0).indexOf("/img/") == 0)?"http://www.which-is-better.net" + p1.getListEnderecoFoto().get(0):p1.getListEnderecoFoto().get(0));
					URL urlP1 = new URL(url1);
					InputStream in = urlP1.openStream();
					Blob blobP1 = new Blob(IOUtils.toByteArray(in));
					Image aImage = ImagesServiceFactory.makeImage(blobP1.getBytes());
					Transform resize = ImagesServiceFactory.makeResize(100, 200, true);
			        Image nAImage = imagesService.applyTransform(resize, aImage);

			        String url2 = ((p2.getListEnderecoFoto().get(0).indexOf("/img/") == 0)?"http://www.which-is-better.net" + p2.getListEnderecoFoto().get(0):p2.getListEnderecoFoto().get(0));
			        URL urlP2 = new URL(url2);
					InputStream in2 = urlP2.openStream();
					Blob blobP2 = new Blob(IOUtils.toByteArray(in2));
					Image bImage = ImagesServiceFactory.makeImage(blobP2.getBytes());
			        Image nBImage = imagesService.applyTransform(resize, bImage);

			        URL urlVersus = new URL("http://" + c.getSiteOriginal().getHost().replace("localhost", "localhost:8888") + "/images/versus.png");
					InputStream in3 = urlVersus.openStream();
					Blob blobVersus = new Blob(IOUtils.toByteArray(in3));
					Image versusImage = ImagesServiceFactory.makeImage(blobVersus.getBytes());

				  	List<Composite> listComposites = new ArrayList<Composite>();
				    Composite aPaste = ImagesServiceFactory.makeComposite(nAImage, 0, 0, 1f, Composite.Anchor.TOP_LEFT);
				    listComposites.add( aPaste );

				    Composite versusPaste = ImagesServiceFactory.makeComposite(versusImage, 101, 50, 1f, Composite.Anchor.TOP_LEFT);
				    listComposites.add( versusPaste );

				    Composite bPaste = ImagesServiceFactory.makeComposite(nBImage, 132, 0, 1f, Composite.Anchor.TOP_LEFT);
				    listComposites.add( bPaste );

				    Image newImage = imagesService.composite(listComposites, 232, 200, 0x00000000L, ImagesService.OutputEncoding.PNG);
				    LinkBlobImage newLinkImageBlobVersus = new LinkBlobImage("", new Blob(newImage.getImageData()));

				    long imgId = gravaNovoLinkBlobImage(newLinkImageBlobVersus, true);
				    if (imgId > 0) {
				    	c.setLinkImageVersus("/img/" + imgId);
				    	System.out.println("Setou a imagem versus!!:[" + c.getLinkImageVersus() + "]");
				    }

				} catch (MalformedURLException ex) {
					ex.printStackTrace();
					return ex.getMessage();
				} catch (IOException ex) {
					ex.printStackTrace();
					return ex.getMessage();
				} catch (Exception ex) {
					result = "Erro ao processar a comparacao:" + c.getId() + " - " + c.getPergunta(c.getSiteOriginal(), c.getLocale());
					result += "   \nImagem 1: " + p1.getListEnderecoFoto().get(0);
					result += "    \nImagem 2: " + p2.getListEnderecoFoto().get(0);
					result += ex.getMessage(); 
					return result;
				}

				if (salvar) {
					if (gravaNovaComparacao(c)) {
						result = "ok";
					} else {
						result += "erro";
					}
				} else {
					result = "ok";
				}
			}
		}

		return result;
	}
}